#!/usr/bin/python3
# -*- coding:utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
# This file is a part of the CANN Open Software.
# Licensed under CANN Open Software License Agreement Version 1.0 (the "License").
# Please refer to the License for details. You may not use this file except in compliance with the License.
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
# See LICENSE in the root of the software repository for the full text of the License.
# ======================================================================================================================
import os
import sys
import logging
import numpy as np

LOSS = 1e-3 # 容忍偏差，一般fp16要求绝对误差和相对误差均不超过千分之一
MINIMUM = 10e-10
# 配置logging
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s'
)


def verify_result(real_result, golden):
    dtype = np.float16
    real_result = np.fromfile(real_result, dtype=dtype)
    golden      = np.fromfile(golden,      dtype=dtype)
    if real_result.size != golden.size:
        logging.error("Shape mismatch: real=%d vs golden=%d", real_result.size, golden.size)
        sys.exit(1)

    abs_diff = np.abs(real_result - golden)
    deno     = np.maximum(np.abs(real_result), np.abs(golden)) + MINIMUM
    rtol     = abs_diff / deno

    # 找到所有不满足 atol 且不满足 rtol 的元素
    bad = ~( (abs_diff <= LOSS) | (rtol <= LOSS) )
    bad_cnt = np.sum(bad)
    if bad_cnt > 0:
        bad_idx = np.where(bad)[0]          # 超差元素的索引
        logging.error("Compare failed!  %d / %d  elements exceed tolerance (LOSS=%.2e)", bad_cnt, real_result.size, LOSS)
        # 最多打印前 20 条，防止刷屏
        for i, idx in enumerate(bad_idx[:1000]):
            logging.error("elem[%d]  golden=%.7e  real=%.7e  abs=%.7e  rel=%.7e",
                          idx, float(golden[idx]), float(real_result[idx]),
                          float(abs_diff[idx]), float(rtol[idx]))
        sys.exit(1)

    logging.info("test pass")
    sys.exit(0)

if __name__ == '__main__':
    verify_result(sys.argv[1],sys.argv[2])
